﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dapper.Orm;

namespace Dapper.Logic.Service
{
    public interface IActionLogicService
    {
        // Multi Fetch
        List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args);
        List<TRet> Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args);
        List<TRet> Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args);

        // Multi Query
        IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args);
        IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args);
        IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args);

        // Multi Fetch (SQL builder)
        List<TRet> Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql);
        List<TRet> Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql);
        List<TRet> Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql);

        // Multi Query (SQL builder)
        IEnumerable<TRet> Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql);
        IEnumerable<TRet> Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql);
        IEnumerable<TRet> Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql);

        // Multi Fetch (Simple)
        List<T1> Fetch<T1, T2>(string sql, params object[] args);
        List<T1> Fetch<T1, T2, T3>(string sql, params object[] args);
        List<T1> Fetch<T1, T2, T3, T4>(string sql, params object[] args);

        // Multi Query (Simple)
        IEnumerable<T1> Query<T1, T2>(string sql, params object[] args);
        IEnumerable<T1> Query<T1, T2, T3>(string sql, params object[] args);
        IEnumerable<T1> Query<T1, T2, T3, T4>(string sql, params object[] args);

        // Multi Fetch (Simple) (SQL builder)
        List<T1> Fetch<T1, T2>(Sql sql);
        List<T1> Fetch<T1, T2, T3>(Sql sql);
        List<T1> Fetch<T1, T2, T3, T4>(Sql sql);

        // Multi Query (Simple) (SQL builder)
        IEnumerable<T1> Query<T1, T2>(Sql sql);
        IEnumerable<T1> Query<T1, T2, T3>(Sql sql);
        IEnumerable<T1> Query<T1, T2, T3, T4>(Sql sql);
    }

    public interface IActionLogicService<T>
    { 
        bool IsNew(T modle);
        object Insert(T modle);
        void Save(T modle);
        int Update(T modle);
        int Update(T modle, IEnumerable<string> columns);
        int Update(string sql, params object[] args);
        int Update(Sql sql);
        int Delete(T modle);
        int Delete(string sql, params object[] args);
        int Delete(Sql sql);
        int Delete(object primaryKey);
        bool Exists(object primaryKey);
        T SingleOrDefault(object primaryKey);
        T SingleOrDefault(string sql, params object[] args);
        T SingleOrDefault(Sql sql);
        T FirstOrDefault(string sql, params object[] args);
        T FirstOrDefault(Sql sql);
        T Single(object primaryKey);
        T Single(string sql, params object[] args);
        T Single(Sql sql);
        T First(string sql, params object[] args);
        T First(Sql sql);
        List<T> Fetch(string sql, params object[] args);
        List<T> Fetch(Sql sql);
        List<T> Fetch(long page, long itemsPerPage, string sql, params object[] args);
        List<T> Fetch(long page, long itemsPerPage, Sql sql);
        List<T> SkipTake(long skip, long take, string sql, params object[] args);
        List<T> SkipTake(long skip, long take, Sql sql);
        Page<T> Page(long page, long itemsPerPage, string sql, params object[] args);
        Page<T> Page(long page, long itemsPerPage, Sql sql);
        IEnumerable<T> Query(string sql, params object[] args);
        IEnumerable<T> Query(Sql sql);
    }
}
